package sessionbeans;

import javax.ejb.Stateless;
import org.jboss.ejb3.annotation.RemoteBinding;
import javax.persistence.*;
import java.util.List;
import entities.*;
/**
 * Session Bean implementation class FeedbackBean
 */
@Stateless
@RemoteBinding(jndiBinding="FeedbackBeanRemote")
public class FeedbackBean implements FeedbackBeanRemote {

	@PersistenceContext
	private EntityManager manager;
	private static final String findHelpRequests ="select h from HelpRequest as h where h.sender = :sender and " +
			"h.receiver = :receiver and h.pending = false and h.answer = true and h.ability = :ability";
    /**
     * Default constructor. 
     */
    public FeedbackBean() {
        // TODO Auto-generated constructor stub
    }
    
	@Override
	public boolean sendFeedback(String senderId, String receiverId, String abilityName, int rating) {
		if(rating < 0 || rating > 5){
			return false;
		}
		RegisteredUser sender = manager.find(RegisteredUser.class, senderId);
		RegisteredUser receiver = manager.find(RegisteredUser.class, receiverId);
		Ability ability = manager.find(Ability.class, abilityName);
		if(!canRate(sender, receiver, ability)){
			return false;
		}
		updateRating(receiver, ability, rating);
		return true;
		
	}
	
	private boolean canRate(RegisteredUser sender, RegisteredUser receiver, Ability ability){
		Query query = manager.createQuery(findHelpRequests);
		query.setParameter("sender", sender);
		query.setParameter("receiver", receiver);
		query.setParameter("ability", ability);
		List<HelpRequest> requests = (List<HelpRequest>) query.getResultList();
		if(requests.size() > 0){
			HelpRequest request = requests.get(0);
			manager.remove(request);
			return true;
		}
		return false;
	}
	
	private int computeAverage(int rate, int size, int oldAverage){
		return (oldAverage * (size - 1) + rate)/size; 
	}
	
	private void updateRating(RegisteredUser receiver, Ability ability, int rating){
		DeclaresPK key = new DeclaresPK(receiver, ability);
		Declares declares = manager.find(Declares.class, key);
		int oldAverage = declares.getRating();
		int newSize = declares.getNumberOfFeedbacks() + 1;
		int newAverage = computeAverage(rating, newSize, oldAverage);
		declares.setNumberOfFeedbacks(newSize);
		declares.setRating(newAverage);
		manager.merge(declares);
	}

}
